package pers.vic.boot.console.student.service;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import pers.vic.boot.base.service.BaseService;
import pers.vic.boot.base.vo.BooleanWithMsg;
import pers.vic.boot.base.vo.Select2VO;
import pers.vic.boot.console.student.mapper.ZblStudentScoreMapper;
import pers.vic.boot.console.student.model.ZblStudentBase;
import pers.vic.boot.console.student.model.ZblStudentScore;
import pers.vic.boot.util.poi.LargeDataRowCallback;
import pers.vic.boot.util.poi.LargeExcelImportFacade;

/**
 * @description: Service
 * @author Vic.xu
 * @date: 2020-06-29 09:35
 */
@Service
public class ZblStudentScoreService extends BaseService<ZblStudentScoreMapper, ZblStudentScore> {
	
	private static Logger logger = LoggerFactory.getLogger(ZblStudentScoreService.class);
	@Autowired
	private ZblStudentBaseService zblStudentBaseService;

	@Override
	protected boolean hasAttachment() {
		return false;
	}
	
	/**
	 * 学期下拉框
	 * 
	 * @return
	 */
	public List<Select2VO> termSelect() {
		List<String> clazzList = mapper.termList();
		return clazzList.stream().map(clazz -> {
			return new Select2VO(clazz, clazz);
		}).collect(Collectors.toList());
	}

	/**
	 * 查询出一个班级全部学生的成绩 根据number降序
	 * 
	 * @param clazz 班级
	 * @param term  学期
	 */
	public List<ZblStudentScore> listByClazz(String clazz, String term) {
		return mapper.listByClazz(clazz, term);
	}

	public void updatePracticeScore(String number, BigDecimal score) {
		mapper.updatePracticeScore(number, score);
	}
	

	/**
	 * 成绩列表转map
	 * 
	 * @param clazz
	 * @return
	 */
	public Map<String, ZblStudentScore> scoreMap(String clazz, String term) {
		List<ZblStudentScore> list = listByClazz(clazz, term);
		return list.stream().collect(Collectors.toMap(ZblStudentScore::getNumber, Function.identity(), (v1, v2)->v2));
	}

	/**
	 * 导入学生成绩;
	 * 表头:
	 * 学号	姓名	平时成绩（40%）	实训结果（30%）	大作业成绩（30%）	最终成绩
	 * @param file
	 * @param term
	 * @param numberType 1-学号 2-学号2
	 * @return
	 */
	public BooleanWithMsg importScore(MultipartFile file, String term, int numberType) {

		List<ZblStudentScore> list = new ArrayList<ZblStudentScore>();
		// 姓名2->L学号 map
		try (InputStream in = file.getInputStream()) {
			LargeExcelImportFacade.init(in).readSheet(1, 2, new LargeDataRowCallback() {
				@Override
				public void callback(Map<String, String> rowData) {
					ZblStudentScore score = new ZblStudentScore();
					String number = rowData.get("学号");
					String name = rowData.get("姓名");
					if (StringUtils.isAnyBlank(name, number)) {
						return;
					}
					BigDecimal s1 = toBigDecimal(rowData.get("平时成绩（40%）"));
					// 实训成绩（30%）
					BigDecimal s2 = toBigDecimal(rowData.get("实训结果（30%）"));
					BigDecimal s3 = toBigDecimal(rowData.get("大作业成绩（30%）"));
					BigDecimal s4 = toBigDecimal(rowData.get("最终成绩"));
					score.setNumber(number);
					score.setDailyScore(s1);
					score.setPracticeScore(s2);
					score.setTaskScore(s3);
					score.setFinalScore(s4);
					score.setName(name);
					score.setTerm(term);
					list.add(score);

				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
		String msg = "成功导入" + list.size() + "条学生分数数据";
		logger.info(msg);
		list.forEach(s->{
			saveOrUpdate(s, numberType);
		});
		return BooleanWithMsg.True().setMessage(msg);
	}
	
	/**
	 * 
	 * @param score
	 * @param numberType  1-学号 2-学号2
	 */
	public void saveOrUpdate(ZblStudentScore score, int numberType) {
		if(numberType == 2) {
			//查找真正的学号
			ZblStudentBase base = zblStudentBaseService.getByNumber2(score.getNumber());
			if(base == null) {
				return;
			}
			score.setNumber(base.getNumber());
			score.setName(base.getName());
		}
		//根据学号和学期查询是否已经录入
		ZblStudentScore old = mapper.findByEntity(score);
		if(old != null) {
			score.setId(old.getId());
		}
		super.save(score);
		
		
	}

	public static BigDecimal toBigDecimal(String str) {
		if (StringUtils.isEmpty(str)) {
			return BigDecimal.ZERO;
		}
		try {
			return new BigDecimal(str).setScale(2, BigDecimal.ROUND_HALF_UP);
		} catch (Exception e) {
			e.printStackTrace();

		}
		return BigDecimal.ZERO;

	}
}
